//写一个自己的多线程类

//具体的类：有自己名字的类，相对的还有一种匿名类
class MyThread extends Thread{
    public void run(){
        while(true){
            System.out.println("你好多线程！");
            try {//sleep需要try catch
                sleep(1000);
            } catch (InterruptedException e) {
                //throw new RuntimeException(e);直接把异常打印出来
                e.printStackTrace();
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程对象
        Thread thread=new MyThread();
        //启动线程
        thread.start();
        /*启动线程不是thread.run()->因为start方法是调用系统api，真正在操作系统内部创建一个线程，这个新的线程就会以run作为入口方法，
        *执行run中的逻辑，而run方法不需要在代码中显示调用*/
        /*用thread.run()虽然也能打印“你好多线程！”，但是没有创建新的线程，而是直接在main方法所在的“主线程”中执行了run的逻辑*/
        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}
/*
在 Java 中，try-catch 语句是用于处理异常的重要机制。异常是在程序执行过程中发生的错误或意外情况，
使用 try-catch 可以捕获并处理这些异常，避免程序因异常而崩溃。
try-catch 语句的基本语法结构如下：
try {
    // 可能会抛出异常的代码块
} catch (ExceptionType1 e1) {
    // 处理 ExceptionType1 类型异常的代码块
} catch (ExceptionType2 e2) {
    // 处理 ExceptionType2 类型异常的代码块
} finally {
    // 无论是否发生异常，都会执行的代码块
}
*/



/*
第一段代码：
public class Demo2 {
    static class MyThread extends Thread{
        public void run(){
            while(true){
                System.out.println("你好多线程！");
                try {//sleep需要try catch
                    sleep(1000);
                } catch (InterruptedException e) {
                    //throw new RuntimeException(e);直接把异常打印出来
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new MyThread();
        thread.start();
        while(true){
                System.out.println("hello main");
                Thread.sleep(1000);
                }
                }
                }
第二段代码：
class MyThread extends Thread{
    public void run(){
        while(true){
            System.out.println("你好多线程！");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程对象
        Thread thread=new MyThread();
        //启动线程
        thread.start();
        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}这两段代码的区别
这两段代码的功能是一致的，都是创建一个自定义线程类 `MyThread`，并在 `main` 方法中启动该线程，同时主线程也会执行一个无限循环打印信息。不过，它们在代码结构上存在一些细微的区别：

### 内部类与外部类的区别
- **第一段代码**：`MyThread` 类被定义为 `Demo2` 类的静态内部类。静态内部类是指被 `static` 修饰的内部类，它可以不依赖于外部类的实例而存在。在这种情况下，`MyThread` 类可以直接访问外部类的静态成员，但不能直接访问外部类的非静态成员。
```java
public class Demo2 {
    static class MyThread extends Thread{
        // ...
    }
    // ...
}
```
- **第二段代码**：`MyThread` 类是一个独立的外部类，它与 `Demo2` 类是平级的关系，不存在内部类与外部类的嵌套关系。
```java
class MyThread extends Thread{
    // ...
}
public class Demo2 {
    // ...
}
```

### 影响和使用场景差异
- **命名空间和封装性**
    - **第一段代码**：将 `MyThread` 定义为静态内部类可以更好地将相关的类组织在一起，提高代码的封装性。`MyThread` 类的作用域被限制在 `Demo2` 类内部，避免了与其他类的命名冲突。
    - **第二段代码**：`MyThread` 作为独立的外部类，在命名上需要更加注意避免与其他类重名，因为它的作用域是整个包。
- **访问外部类成员**
    - **第一段代码**：如果 `Demo2` 类中有静态成员，`MyThread` 类可以直接访问这些静态成员。例如，如果 `Demo2` 类中有一个静态变量 `static int count`，`MyThread` 类可以直接使用 `count`。
    - **第二段代码**：由于 `MyThread` 是独立的外部类，它不能直接访问 `Demo2` 类的成员，除非通过创建 `Demo2` 类的实例或者使用 `Demo2` 类的静态方法和变量。
- **代码复用和扩展性**
    - **第一段代码**：`MyThread` 类的复用性相对较低，因为它与 `Demo2` 类紧密耦合。如果需要在其他类中使用 `MyThread` 类，可能需要将其提取为独立的外部类。
    - **第二段代码**：`MyThread` 类作为独立的外部类，具有更好的复用性和扩展性，可以在其他类中直接使用，而不需要依赖于 `Demo2` 类。

总体而言，这两段代码在功能上是等价的，但在代码结构和使用场景上存在一些差异，你可以根据具体的需求选择合适的代码结构。
*/



/*第一段代码，MyThread为什么必须设置为静态的
* 在第一段代码中，将 `MyThread` 类设置为静态内部类（`static class MyThread`）主要是基于 Java 内部类的特性和代码的使用场景考虑，下面详细解释其原因。

### 静态内部类与非静态内部类的区别
在 Java 里，内部类分为静态内部类和非静态内部类（也叫实例内部类）。非静态内部类会隐式持有外部类的一个引用，而静态内部类则不会持有外部类的引用。

### 为什么这里 `MyThread` 要设为静态
#### 1. 无需外部类实例即可创建
在 `main` 方法（它是静态方法）中创建 `MyThread` 类的实例时，如果 `MyThread` 是非静态内部类，就必须先创建外部类 `Demo2` 的实例，然后通过外部类实例来创建 `MyThread` 实例。示例如下：
```java
public class Demo2 {
    class MyThread extends Thread{
        public void run(){
            while(true){
                System.out.println("你好多线程！");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 先创建外部类实例
        Demo2 demo2 = new Demo2();
        // 通过外部类实例创建内部类实例
        Thread thread = demo2.new MyThread();
        thread.start();

        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}
```
但将 `MyThread` 定义为静态内部类后，就可以直接创建 `MyThread` 实例，无需先创建外部类 `Demo2` 的实例，代码会更简洁：
```java
public class Demo2 {
    static class MyThread extends Thread{
        public void run(){
            while(true){
                System.out.println("你好多线程！");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 直接创建 MyThread 实例
        Thread thread = new MyThread();
        thread.start();

        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}
```

#### 2. 避免不必要的引用关系
非静态内部类会持有外部类的引用，这可能会导致内存泄漏等问题。在本案例中，`MyThread` 类不需要访问外部类 `Demo2` 的非静态成员，将其定义为静态内部类可以避免这种不必要的引用关系，减少内存开销和潜在的问题。

综上所述，将 `MyThread` 设置为静态内部类，既简化了在 `main` 方法中创建 `MyThread` 实例的过程，又避免了不必要的引用关系，是一种更合适的设计选择。 */